﻿using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;
using T0yK4T.IO;
using T0yK4T.Tools;

namespace TestProject
{
    public partial class Mainform : Form, ILogger
    {
        CryptoConnection clientConnection = new CryptoConnection(new ConsoleLogger(), CryptoConnectionFlags.None);
        CryptoConnection serverConnection = new CryptoConnection(new ConsoleLogger(), CryptoConnectionFlags.None);
        private TcpClient client = new TcpClient();
        private TcpClient serverSideClient;
        private TcpListener listener = new TcpListener(new IPEndPoint(IPAddress.Loopback, 5000));

        public Mainform()
        {
            InitializeComponent();
            this.clientConnection.MaxKeyAge = TimeSpan.FromSeconds(30);
            this.clientConnection.MaxAgeSkew = TimeSpan.FromSeconds(1);
        }

        private void WriteLine(string line)
        {
            this.textBox1.Text += line + Environment.NewLine;
            this.textBox1.Select(this.textBox1.Text.Length, 0);
            this.textBox1.ScrollToCaret();
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            base.OnClosing(e);
            try { this.clientConnection.Close(); }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
            try { this.serverConnection.Close(); }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }

        public void Log(LoggingType type, object sender, string message)
        {
            try
            {
                Console.WriteLine("LOG: [{0}:{1}]:{2}", type.ToString()[0], sender.GetType().FullName, message);
            }
            catch { }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.listener.Start();
            listener.BeginAcceptTcpClient(this.OnAcceptTcpClient, listener);
            this.client = new TcpClient();
            client.Connect(new IPEndPoint(IPAddress.Loopback, 5000));

            clientConnection.PacketReceived += new PacketReceivedDelegate((p, i) =>
                {
                    this.WriteLine(string.Format("Client Received: {0} bytes", i));
                    this.WriteLine(string.Format("Client - Message: {0}", PacketFactory.DeGenerateASCIIPacket(p)));
                });
            clientConnection.WrapSocket(client.Client);
            if (clientConnection.Connected)
                this.button2.Enabled = true;
            else
                MessageBox.Show("Unable to connect :(");
        }

        private void OnAcceptTcpClient(IAsyncResult res)
        {
            TcpListener listener = (TcpListener)res.AsyncState;
            this.serverSideClient = listener.EndAcceptTcpClient(res);
            listener.Stop();
            serverConnection.PacketReceived += new PacketReceivedDelegate((p, i) =>
                {
                    this.WriteLine(string.Format("Server Received: {0} bytes", i));
                    this.WriteLine(string.Format("Server - Message: {0}", PacketFactory.DeGenerateASCIIPacket(p)));
                });
            serverConnection.WrapSocket(this.serverSideClient.Client);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                this.serverConnection.SendPacket(PacketFactory.GenerateASCIIPacket(Program.message));
                this.clientConnection.SendPacket(PacketFactory.GenerateASCIIPacket(Program.message));
            }
            catch { }
        }
    }
}
